<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>打开控制台查看结果</div>
    <script>
        /* 适配器模式的作用是解决两个软件实体间的接口不兼容问题。使用适配器模式之后，原本由于
        接口不兼容而不能工作的两个软件实体可以一起工作。
           在程序开发中有许多这样的场景：
           当我们视图调用模块或者对象的某个接口时，却发现这个接口的格式并不符合目前的需求。这时候有两种解决办法，第一种是修改原来的接口实现，
           但如果原来的模块很复杂，或者我们拿到的模块是一段别人编写经过压缩的代码，修改原接口就显得不太现实。第二种办法是创建一个适配器，
           将原接口转换为客户希望的另一个接口，客户只需要和适配器打交道。
        */
       /* 例如： */
       (function(){
            class GooleMap {
            show() {
                console.log('渲染谷歌地图');
            }
        }

        class BaiduMap {
            show() {
                console.log('渲染百度地图');
            }
        }

        function render(map) {
            if(map.show instanceof Function){
                map.show()
            }
        }

        render(new GooleMap()); // 渲染谷歌地图
        render(new BaiduMap()); // 渲染百度地图
       })();


       /* 上面例子中成功渲染的结果，但如果，BaiduMap的原型方法不教show，而叫disPlay，
       那么上面的调用就不生效了，这时就可以使用适配器模式，因为我们不能轻易改变第三方的内容。
       在BaiduMap的基础上封装一层，对外暴露show方法。
       */
      (function(){
        class GooleMap {
            show() {
                console.log('渲染谷歌地图2');
            }
        }

        class BaiduMap {
            display() {
                console.log('渲染百度地图2');
            }
        }

        // 定义适配器类，对BaiduMap类进行封装
        class BaiduMapAdapter {
            // 通过show方法调用
            show() {
                let baiduMap = new BaiduMap()
                return baiduMap.display(); // 返回display
            }
        }

        function render(map) {
            if(map.show instanceof Function) {
                map.show();
            }
        }

        render(new GooleMap());  // 渲染谷歌地图2
        render(new BaiduMapAdapter());  // 渲染百度地图2

      })();

      /* 
        1、适配器模式主要解决两个接口之间不匹配的问题，不会改变原有的接口，而是由一个对象对另一个对象的包装。
        2、适配器模式符合开放封闭原则
      */



      console.log('============练习============');
      (function(){
        class GooleMap {
            show(){
                console.log('渲染谷歌地图3');
            }
        }
        class BaiduMap {
            // 如果这里不叫show，而叫display
            display() {
                console.log('渲染百度地图3');
            }
        }

        /**
         * 定义适配器类，对BaiduMap类进行封装
        */
       class BaiduMapAdapter {
        // 将display方法通过show方法封装返回
        show() {
            let baidu = new BaiduMap();
            return baidu.display(); // 返回display
        }
       }

       function render(map) {
        // 传入的map就是实例化的类，直接调用show方法
        map.show instanceof Function ? map.show() : '不是一个函数'
       }

       render(new GooleMap()); // 调用谷歌地图3
       render(new BaiduMapAdapter()); // 调用百度地图3


      })()


    </script>
</body>
</html>